package com.vandytrack.web.client;

import java.util.List;
import java.lang.Math;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.control.SmallMapControl;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.vandytrack.web.query.QueryService;
import com.vandytrack.web.query.QueryServiceAsync;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class VandyTrackWeb implements EntryPoint {

	@SuppressWarnings("unused")
	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = "An error occurred while "
			+ "attempting to contact the server. Please check your network "
			+ "connection and try again.";

	protected double VANDY_LAT = 36.142830;
	protected double VANDY_LONG = -86.804437;
	protected int count = 0;

	private MapWidget map;
	public Marker vanderbiltMarker;

	/**
	 * Create a remote service proxy to talk to the server-side Greeting
	 * service.
	 */
	// private final GreetingServiceAsync greetingService = GWT
	// .create(GreetingService.class);

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		/*
		 * Add a handler to send the name to the server MyHandler handler = new
		 * MyHandler(); sendButton.addClickHandler(handler);
		 * nameField.addKeyUpHandler(handler);
		 */

		HorizontalPanel hp = new HorizontalPanel();
		RootPanel.get().add(hp);

		LatLng vanderbiltLocation = LatLng.newInstance(VANDY_LAT, VANDY_LONG);
		// Open a map centered on Vanderbilt University.
		vanderbiltMarker = new Marker(vanderbiltLocation);

		map = new MapWidget(vanderbiltLocation, 15);
		map.setSize("600px", "600px");

		// Add some controls for the zoom level
		map.addControl(new SmallMapControl());

		// Add a marker
		map.addOverlay(vanderbiltMarker);

		// Add an info window to highlight a point of interest
		// map.getInfoWindow().open(map.getCenter(),
		// new InfoWindowContent("Vanderbilt University"));

		String initToken = "";
		initToken = Window.Location.getParameter("test");

		// Create a textView to output on the screen which states whether or
		// not the token was received successfully.
		final TextArea ta = new TextArea();
		ta.setReadOnly(true);
		ta.setSize("200px", "600px");

		if (initToken == "test") {
			ta.setText("Success!");
		} else {
			ta.setText("Failed. \"test\" not found");
		}

		hp.add(ta);
		hp.add(map);

		// Setup a timer for testing map pin moving.
		Timer myTimer = new Timer() {
			@SuppressWarnings("unchecked")
			public void run() {

				VanLocation loc = new VanLocation();
				LatLng latlng = vanderbiltMarker.getLatLng();
				loc.setValues(2534, 2, 37000, 32, latlng.getLatitude() + .0005,
						latlng.getLongitude() + .0005, 88, 000);
				if (loc != null) {
					vanderbiltMarker.setLatLng(LatLng.newInstance(loc
							.getLatitude(), loc.getLongitude()));
					ta.setText("VehicleID: "
							+ loc.getDriverID()
							+ "\nLat: "
							+ loc.getLatitude()
							+ "\nLong: "
							+ loc.getLongitude()
							+ "\nSpeed: "
							+ loc.getSpeed()
							+ "\nAverage Speed: "
							+ getAverageSpeed(latlng, vanderbiltMarker
									.getLatLng()));
				}

				// (1) Create the client proxy.
				QueryServiceAsync queryService = (QueryServiceAsync) GWT
						.create(QueryService.class);

				// (2) Create an asynchronous callback to handle the result.
				AsyncCallback callback = new AsyncCallback() {

					@Override
					public void onSuccess(Object result) {
						// TODO Auto-generated method stub
						ta.setText((String)result);
					}

					public void onFailure(Throwable caught) {
						// do some UI stuff to show failure.
					}

				};

				// (3) Make the call. Control flow will continue immediately
				// and later 'callback' will be invoked when the RPC completes.
				queryService.getCurrentLocations("poo", callback);
			}
		};

		// Schedule timer to run every 3 seconds...repeating of course.
		myTimer.scheduleRepeating(3000);

	}

	// Pulled method from http://www.movable-type.co.uk/scripts/latlong.html
	// 1 meter = 0.000621371192 miles
	public String getAverageSpeed(LatLng oldLoc, LatLng newLoc) {
		// Calculate the distance between two points
		int R = 6371; // km
		double dLat = newLoc.getLatitudeRadians() - oldLoc.getLatitudeRadians();
		double dLon = newLoc.getLongitudeRadians()
				- oldLoc.getLongitudeRadians();
		double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
				+ Math.cos(oldLoc.getLatitudeRadians())
				* Math.cos(newLoc.getLatitudeRadians()) * Math.sin(dLon / 2)
				* Math.sin(dLon / 2);
		double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
		double d = R * c;

		// Average speed = distance/time
		// (meters/seconds) * (3600seconds/hour) * (.621371192miles/meter) =
		// miles/hour
		double avgSpeed = (d / 3) * 3600 * .621371192;
		return String.valueOf(avgSpeed);
	}
}
